package cn.edu.nuaa.aadl2.generatorC.template

import org.osate.aadl2.Feature
import org.osate.aadl2.DataPort
import org.osate.aadl2.DirectionType
import java.util.List

import static extension cn.edu.nuaa.aadl2.generatorC.utils.StringUtils.*
import static extension cn.edu.nuaa.aadl2.generatorC.utils.PropertyParser.*
import static extension cn.edu.nuaa.aadl2.generatorC.template.DataTemplate.*
import org.osate.aadl2.Parameter
import org.osate.aadl2.EventPort
import org.osate.aadl2.EventDataPort
import cn.edu.nuaa.aadl2.generatorC.utils.Tools
import org.osate.aadl2.Classifier
import org.osate.aadl2.DataClassifier
import org.osate.aadl2.instance.PropertyAssociationInstance
import org.osate.aadl2.NamedValue
import org.osate.aadl2.DataAccess
import org.osate.aadl2.SubprogramAccess

/*
 * Feature a
 * feature as method parameter while call method, eg: f(a);
 * feature as variable, eg: int a;
 * feature as variable in method defination,eg: int f(int a);
 * */
class FeatureTemplate {
	
	static String folder="";
	def static setFolder(String folder1){
		
		folder=folder1;
	}
		/*
	 * 处理系统类型声明中的features
	 * @param folderPath 此系统目录路径
	 * @param systemName 此系统名
	 * @param features 系统类型声明中的features列表
	 */
	def static genSystemFeature(String folderPath, String systemName, List<Feature> features){
		Tools.createFile(folderPath,systemName.convert+"_feature.h",systemFeature(features).toString())
	}
	
	def static systemFeature( List<Feature> features)'''
	/***********************************
	* deal with system feature!!!!	start!
	************************************/
			«FOR Feature feature : features»
«««				«IF feature.classifier !== null»«feature.classifier.name.convertPoint»«ELSE»Boolean«ENDIF» «feature.name» ;
				«feature.template»
			«ENDFOR»
	/************************************
	* deal with system feature!!!!	end!
	************************************/	
	'''
	
	def static dealRequireDataAccess(List<Feature> features)'''
		«FOR feature:features»
			«feature.getFeatureClassifier0.toString.clearspace» «feature.name»,
		«ENDFOR»
	'''
	def static dealRequireDataAccessOnly4ParaName(List<Feature> features)'''
		«FOR feature:features»
			«feature.name»,
		«ENDFOR»
	'''	

	def static getFeatureClassifier0(Feature feature){
		if(feature.classifier!=null){
			var f=feature.classifier.name.convertNo2Low
			switch f{
				case "Integer":
					return "int"
				default:
					return f
			}
		}else{
			return feature.name +"'s classifier is null. error in FeatureTemplate line 58"
		}
	}
	def static template(Feature feature){
		switch feature{
			DataPort : '''
				«IF feature.direction.equals(DirectionType.IN)»
				extern «feature.featureClassifier0.toString.clearspace» «feature.name.convertNo2Low»;
				«ENDIF»
				«IF feature.direction.equals(DirectionType.OUT)»«ENDIF»
				«IF feature.direction.equals(DirectionType.IN_OUT)»«ENDIF»
			'''
			EventPort : '''
			Unhandeled EventPort at FeatureTemplate.xtend line 76
			'''
			EventDataPort : '''
				//EventDataPort
				«IF feature.direction.equals(DirectionType.IN)»
				extern «feature.featureClassifier0.toString.clearspace» «feature.name.convertNo2Low»;
				«ENDIF»
				«IF feature.direction.equals(DirectionType.OUT)»«ENDIF»
				«IF feature.direction.equals(DirectionType.IN_OUT)»«ENDIF»
			'''
			Parameter : '''
			Unhandeled Patameter at FeatureTemplate.xtend line 87
			'''
			SubprogramAccess:'''
			//feature subprogramaccess 通过引用对应子程序的头文件实现
			extern void «feature.featureClassifier0.toString.clearspace»(paras...);
			'''
			DataAccess:'''
«««			/*此处应该是个全局变量的概念,应该在上层的process 或 system中定义*/
			/* global */
			extern «feature.featureClassifier0.toString.clearspace» «feature.name.convertNo2Low»;
			«FOR property: feature.ownedPropertyAssociations»
			«property.property.fullName» : «property.property.ownedPropertyType»
			«ENDFOR»
			
			'''
		}		
	}
	def static vectorIfHad(Feature feature){
		if(Template.connections.get(feature.name.convertNo2Low)!=null)
			return "=&"+feature.name.convertNo2Low
	}
	
	  
	def static asDefinations(List<Feature> features)'''
		«FOR Feature feature : features»
			«feature.datadefination.toString.clear»
			«IF !feature.equals(features.get(features.size-1))»«(feature.asDefination+",").toString.clearspace»«ENDIF»
			«IF feature.equals(features.get(features.size-1))»«feature.asDefination»«ENDIF»
		«ENDFOR»
	'''
	
	def static asDefination(Feature feature){
		switch feature{
			Parameter : '''
				«IF feature.direction.equals(DirectionType.IN)»
					«feature.getFeatureClassifier0.toString.clearspace» «feature.name.convert»
				«ENDIF»
				«IF feature.direction.equals(DirectionType.OUT)»
					«feature.getFeatureClassifier0.toString.clearspace» *«feature.name.convert»
				«ENDIF»					
				«IF feature.direction.equals(DirectionType.IN_OUT)»
					
				«ENDIF»
			'''
			EventPort : ''''''
			EventDataPort : ''''''
			DataPort : '''
				«IF feature.direction.equals(DirectionType.IN)»
					«feature.getFeatureClassifier0.toString.clearspace» «feature.name.convert»
				«ENDIF»
				«IF feature.direction.equals(DirectionType.OUT)»
					«feature.getFeatureClassifier0.toString.clearspace» *«feature.name.convert»
				«ENDIF»					
				«IF feature.direction.equals(DirectionType.IN_OUT)»
					
				«ENDIF»
			'''
		}	
	}
	
	def static asParameters(List<Feature> features)'''
		«FOR Feature feature : features»
			«feature.datadefination.toString.clear»
			«IF !feature.equals(features.get(features.size-1))»«(feature.asParameter+",").toString.clearspace»«ENDIF»
			«IF feature.equals(features.get(features.size-1))»«feature.asParameter»«ENDIF»
		«ENDFOR»
	'''
	
	def static asParameter(Feature feature){
		switch feature{
			Parameter : '''
				«IF feature.direction.equals(DirectionType.IN)»
					«feature.name.convert»
				«ENDIF»
				«IF feature.direction.equals(DirectionType.OUT)»
					«feature.name.convert»
				«ENDIF»					
				«IF feature.direction.equals(DirectionType.IN_OUT)»
					«feature.name.convert»
				«ENDIF»
			'''
			EventPort : ''''''
			EventDataPort : ''''''
			DataPort : ''''''
		}
	}
	
	def static asVariables(List<Feature> features)'''
		«FOR Feature feature : features»
			«feature.datadefination.toString.clear»
			«(feature.asVariable+";").toString.clearspace»
		«ENDFOR»
	'''
	
	def static asVariable(Feature feature){
		switch feature{
			Parameter : '''
				«IF feature.direction.equals(DirectionType.IN)»
					«feature.getFeatureClassifier0.toString.clearspace» «feature.name.convert»
				«ENDIF»
				«IF feature.direction.equals(DirectionType.OUT)»
					«feature.getFeatureClassifier0.toString.clearspace» *«feature.name.convert»
				«ENDIF»					
				«IF feature.direction.equals(DirectionType.IN_OUT)»
					
				«ENDIF»
			'''			
			EventPort : ''''''
			EventDataPort : ''''''
			DataPort : '''
				«IF feature.direction.equals(DirectionType.IN)»
					«feature.getFeatureClassifier0.toString.clearspace» «feature.name.convert»
				«ENDIF»
				«IF feature.direction.equals(DirectionType.OUT)»
					«feature.getFeatureClassifier0.toString.clearspace» *«feature.name.convert»
				«ENDIF»					
				«IF feature.direction.equals(DirectionType.IN_OUT)»
					
				«ENDIF»
			'''
		}
	}
	
	def static  datadefination(Feature feature)'''
		«feature.classifier.featuredata»
	'''
	
	def static featuredata(Classifier classifier){
		switch classifier{
			DataClassifier : '''
			«println("set system first in FeatureTemplate!!")»
			«classifier.dataType(folder)»'''
		}
	}
}